import { formatDate, formatNumber } from '@angular/common';
import { QueryList, ViewChildren } from '@angular/core';
import { I18nComponent } from '../../common/i18n/i18n.component';
import { isDate, isObject } from '../../util';
import { OnReuseDestroy, OnReuseInit } from '../reuse-hooks';
import { Base } from './base';



/**
 * 基础类包含业务组件需要用到的常用属性和方法
 */
export class BaseView<U, B, S> extends Base<U, B, S> implements OnReuseInit, OnReuseDestroy {

  @ViewChildren(I18nComponent) i18nGroups: QueryList<any>;

  /**
   * 邮箱正则
   */
  emailRegExp = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/i;

  /**
   * url 正则
   */
  urlRegExp = /^[a-zA-z]+:\/\/[^\s]+$/i;

  /**
   * 电话号码正则
   */
  telRegExp = /^(\d{3,4}-\d{7,8})$/;

  /**
   * 手机号正则
   */
  mobileRegExp = /^((1[358][0-9])|(14[57])|(17[0678])|(19[7])|(16\d))\d{8}$/;

  numberRegExp = /^(-|)(\d+|\d+\.\d*)$/;

  /**
   * 限制输入只能精确到小数点后两位，而且必须是正数
   * 示例 <bz-form-item bzLabel='商品总价' [bzConfig]='{rule: priceRule}' ></bz-form-item>
   */
  priceRule = '^(0|0\\.|0\\.\\d{1,2}|[1-9]\\d*(\\.\\d{0,2}|))$';
  /**
   * 限制输入只能精确到小数点后两位
   */
  allPriceRule = '^(-|(-|)0|(-|)0\\.|(-|)0\\.\\d{1,2}|(-|)[1-9]\\d*(\\.\\d{0,2}|))$';
  /**
   * 限制输入框只能输入正整数
   * 示例 <bz-form-item bzLabel='商品数量' [bzConfig]='{rule: intRule}' ></bz-form-item>
   */
  intRule = '^[1-9]\\d*$';
  /**
   * 限制输入框只能输入正整数和0
   */
  intAndZeroRule = '^(0|[1-9]\\d*)$';
  /**
   * 限制输入框只能输入正整数 0 负整数
   */
  allIntRule = '^(0|-|(-|)[1-9]\\d*)$';



  constructor() {
    super();
  }

  /**
  * 仅在dataGrid中字段需要日期格式化时使用，其他情况请用框架默认的日期管道符
  * 示例 <dxi-column dataField='time' [customizeText]='formatDateTimeForDev' caption='创建时间'></dxi-column>
 */
  formatDateForDev(item: { value: string | number | Date }): string {
    return item.value && formatDate(item.value, 'yyyy-MM-dd', 'zh-cn');
  }
  formatDateTimeForDev(item: { value: string | number | Date }): string {
    return item.value && formatDate(item.value, 'yyyy-MM-dd HH:mm:ss', 'zh-cn');
  }
  formatTimeForDev(item: { value: string | number | Date }): string {
    return item.value && formatDate(item.value, 'HH:mm:ss', 'zh-cn');
  }

  /**
   * 仅在dataGrid中字段需要数字格式化时使用，其他情况请用框架默认的数字管道符
   * 示例 <dxi-column dataField='payTotal' caption='支付金额' [customizeText]='formatNumberForDev'></dxi-column>
   */
  formatNumberForDev(item: { value: number }) {
    return item.value !== null && item.value !== undefined && formatNumber(item.value, 'zh-cn', '.2-2');
  }

  /**
   * 验证数组里面的日期必须在一个规定的时间段内
   * @param arrDate 日期数组
   * @param maxRange 单位：天
   */
  validateDateTimeRange(arrDate: Date[], maxRange: number) {
    if (!arrDate || arrDate.length !== 2 || !isDate(arrDate[0]) || !isDate(arrDate[1])) {
      return false;
    } else {
      const sTime = arrDate[0];
      const eTime = arrDate[1];
      return eTime.getTime() - sTime.getTime() <= 3600 * 1000 * 24 * maxRange;
    }
  }

  /** 切换dataGrid组件行的masterDetail显示和隐藏 */
  toggleShowMasterDetail(row) {
    if (row.component.isRowExpanded(row.data)) {
      row.component.collapseRow(row.data);
    } else {
      row.component.expandRow(row.data);
    }
  }

  /** 变量比对的快捷方式 */
  compareWithFn(byKeys: string[] | string) {
    if (typeof byKeys === 'string') {
      byKeys = [byKeys];
    }

    return (o1, o2) => {
      return (<string[]>byKeys).every((key) => {
        if (!!o1 && !!o2) {
          if (isObject(o1) || isObject(o2)) {
            return o1[key] === o2[key];
          } else {
            // tslint:disable-next-line:triple-equals
            return o1[key] == o2[key];
          }
        } else {
          return false;
        }
      });
    };
  }

  /** 弹出信息提醒并延迟1秒刷新当前页面 */
  refresh(msg?) {
    if (msg) {
      this.messageService.success(msg);
    }

    setTimeout(() => {
      this.broadcastService.emit(<any>'RefreshNavTab');
    }, 1000);
  }

  matchAcl(aclCode: string) {
    return this.aclService.includeAclCode(aclCode);
  }

  /** 获取国际化翻译结果 */
  getI18nValue(itemKey: string, groupKey?: string) {
    let value = '';

    if (groupKey) {
      value = this.i18nService.getValue(itemKey, groupKey);
    } else {
      this.i18nGroups.find((group) => {
        if (group.getValue(itemKey)) {
          value = group.getValue(itemKey);
          return true;
        }
      });
    }

    return value ? value : this.i18nService.getValue(itemKey);
  }

  reuseOnDestroy(): void {
  }

  reuseOnInit(): void {
  }
}
